package com.lmb.controller;

import com.lmb.bean.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@RequestMapping("/common")
@RestController
public class CommonController {

    @Value("${reggie.upload-path}")
    private String uploadPath;

    /**
     * 文件上传
     * 	优化1：如果不同的用户上传的相同名称的文件，会导致后上传覆盖前面上传的，因此对于用户上传到服务器的文件需要进行重命令，防止被覆盖
     * 		  重命名后的文件名称应该是唯一的，如何保证文件名是唯一的：使用UUID  完成文件名称：filename=uuid+后缀名;
     * 	优化2：文件上传服务器保存位置是硬编码，不方便修改，可以将其放在配置文件application.yml中进行设置
     *  注意：文件上传测试 需要先登录后台系统
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public R<String> upload(MultipartFile file) throws IOException {
        //获取用户上传的文件名称
        String originalFilename = file.getOriginalFilename();

        //重命名上传的文件
        String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        log.info("新文件名：{}",fileName);

        //配置文件设置文件上传路径 判断该目录是否存在，如果不存在，就创建
        File dirFile = new File(uploadPath);
        if (!dirFile.exists()){
            dirFile.mkdirs(); //如果目录不存在 就进行级联创建
        }

        //将上传的文件 保存到指定位置
        file.transferTo(new File(uploadPath+fileName));

        //响应上传成功的文件名称
        return R.success(fileName);

    }

    /**
     * 文件下载
     * @param name
     * @param response
     */
    @GetMapping("/download")
    public void download(String name, HttpServletResponse response) throws Exception {
        //文件下载的本质：将服务器上要下载的文件的流写给客户端浏览器  需要使用流的读写 FileInputStrean，ServletOutputStream
        //1.根据要下载的文件名称 去文件上传路径下获取要下载文件的字节输入流
        FileInputStream is = new FileInputStream(uploadPath + name);

        //2.使用response对象获取字节输出流
        ServletOutputStream os = response.getOutputStream();

        //3.循环读写
        byte[] b = new byte[8192];
        int len = -1;
        while((len=is.read(b))!=-1){
            os.write(b,0,len);
        }

        //4.关闭流
        os.close();
        is.close();
    }


}
